package com.hns.tool.pub;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * 日期、时间工具类
 * @author:Fisher
 * @email:zhuangcaijin@126.com
 * @version Revision 2.0.0
 */
public class UtilDatetime {
	public static void main(String[] args){
//        System.out.println(getCurrentTime());
//        System.out.println(formatDate(new Date(),null));
//        System.out.println(parseDate("201-1-04-14"));
//        System.out.println(parseDate2("20110414"));
//        System.out.println(addDay(new Date(),1));
//		  System.out.println(formatDate(new Date(),"yyyyMMddHHmmssSSS"));
			
//		  System.out.println(parseDate("6:00","HH:mm"));
		  
//		  Date from = getCurrentDate();
		  
//		  Date to = add(from, Calendar.DATE, 4);
		  /*
		  System.out.println(compareTime(from,to));
		  字母  日期或时间元素  表示  示例  
		  G  Era 标志符  Text  AD  
		  y  年  Year  1996; 96  
		  M  年中的月份  Month  July; Jul; 07  
		  w  年中的周数  Number  27  
		  W  月份中的周数  Number  2  
		  D  年中的天数  Number  189  
		  d  月份中的天数  Number  10  
		  F  月份中的星期  Number  2  
		  E  星期中的天数  Text  Tuesday; Tue  
		  a  Am/pm 标记  Text  PM  
		  H  一天中的小时数（0-23）  Number  0  
		  k  一天中的小时数（1-24）  Number  24  
		  K  am/pm 中的小时数（0-11）  Number  0  
		  h  am/pm 中的小时数（1-12）  Number  12  
		  m  小时中的分钟数  Number  30  
		  s  分钟中的秒数  Number  55  
		  S  毫秒数  Number  978  
		  z  时区  General time zone  Pacific Standard Time; PST; GMT-08:00  
		  Z  时区  RFC 822 time zone  -0800  
		*/
//		  System.out.println(getFormatTime());
		 long a = 1351140600000L;
		 
		 Date d = new Date(a);
		 System.out.println(getFormatTime(d,"yyyy-MM-dd HH:mm:ss"));
		  
	}
	
	/**
	 * 得到当前日期
	 * @return 当前日期
	 * @author:Fisher
	 * @email:zhuangcaijin@126.com
	 */
	public static Date getCurrentDate(){
		return new Date();
	}
	
	/**
	 * 当前日期字符串(yyyy-MM-dd HH:mm:ss)
	 * @return 日期字符串
	 * @author:Fisher
	 * @email:zhuangcaijin@126.com
	 */
	public static String getFormatTime(){
		return formatDate(new Date(),"yyyy-MM-dd HH:mm:ss");
	}
	
	/**
	 * 日期字符串
	 * @param date 日期
	 * @return 日期字符串
	 * @author:Fisher
	 * @email:zhuangcaijin@126.com
	 */
	public static String getFormatTime(Date date){
		return formatDate(date,null);
	}
	
	/**
	 * 日期字符串
	 * @param date 日期
	 * @param pattern 日期字符串格式
	 * @return 日期字符串
	 * @author:Fisher
	 * @email:zhuangcaijin@126.com
	 */
	public static String getFormatTime(Date date, String pattern){
		return formatDate(date,pattern);
	}
	
	/**
	 * 得到当前时间戳
	 * @return 时间戳
	 * @author:Fisher
	 * @email:zhuangcaijin@126.com
	 */
	public static Timestamp getCurrentTime(){
		return new Timestamp(System.currentTimeMillis());
	}
		
	/**
	 * 日期字符串
	 * @param date 日期
	 * @param pattern 日期字符串格式
	 * @return 日期字符串
	 * @author:Fisher
	 * @email:zhuangcaijin@126.com
	 */
	public static String formatDate(Date date, String pattern) {
        if (date == null) return null;
        if (pattern == null || pattern.trim().length() == 0) pattern = "yyyy-MM-dd";
        try{
            SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        	return  sdf.format(date);
        }catch(Exception e){
        	return null;
        }
    }
	
	/**
	 * 得到指定格式日期
	 * @param date 日期字符串
	 * @param pattern 日期格式
	 * @return 指定格式日期
	 * @author:Fisher
	 * @email:zhuangcaijin@126.com
	 */
	public static Date parseDate(String date,String pattern){
		if ((date == null) || (date.equals(""))) {
            return null;
		}
		if (pattern == null || pattern.trim().length() == 0){
			return parseDate(date);
		}
		
		try{
			SimpleDateFormat formatter = new SimpleDateFormat(pattern);
			return formatter.parse(date);
		}catch(Exception e){
			System.out.println(e.getMessage());
			return null;
		}
	}
	
	/**
	 * 精确到纳秒
	 * @param t 时间戳
	 * @param ref 对比用时间戳
	 * @return 校验后的时间戳
	 * @author:Fisher
	 * @email:zhuangcaijin@126.com
	 */
	public static Timestamp exact2Nanos(Timestamp t, Timestamp ref) {
		if (t != null && ref != null) {
			if (t.getNanos() != ref.getNanos()) {
				t.setNanos(t.getNanos() / 1000000 * 1000000
						+ (ref.getNanos() / 1000));
			}
		}
		return t;
	}
	
	/**
	 * 精确时间到毫秒
	 * @param millis 毫秒
	 * @return 日期
	 * @author:Fisher
	 * @email:zhuangcaijin@126.com
	 */
	public static Date addSandMS(long millis){
		return addSandMS(new Date(millis));
	}
	
	/**
	 * 精确时间到毫秒
	 * @param date 日期
	 * @return 日期
	 * @author:Fisher
	 * @email:zhuangcaijin@126.com
	 */
	public static Date addSandMS(Date date){
		return addSandMS(date,null);
	}
	
	/**
	 * 得到修正精确到毫秒的日期
	 * @param date 日期
	 * @param refDate 对比日期
	 * @return 修改后的日期
	 * @author:Fisher
	 * @email:zhuangcaijin@126.com
	 */
	//TODO
	public static Date addSandMS(Date date,Date refDate){
		Calendar current=Calendar.getInstance();
		Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        if(refDate!=null){
        	cal.setTime(refDate);
        }
        int s=cal.get(Calendar.SECOND);
        int ms=cal.get(Calendar.MILLISECOND);
        if(s==0&&ms==0){
        	cal.set(Calendar.SECOND, current.get(Calendar.SECOND));
        	cal.set(Calendar.MILLISECOND, current.get(Calendar.MILLISECOND));
        }
        if(ms==0){
        	cal.set(Calendar.MILLISECOND, current.get(Calendar.MILLISECOND));
        }
        return cal.getTime();
	}
	
	/**
	 * 日期字符串解析为日期
	 * @param date 日期字符串
	 * @return 日期
	 * @author:Fisher
	 * @email:zhuangcaijin@126.com
	 */
	public static Date parseDate(String date) {
		if ((date == null) || (date.equals(""))) {
            return null;
		} 
		
        try {
        	SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            return formatter.parse(date);
        } catch (ParseException e) {
            return null;
        }     
    }
    
	/**
	 * 日期字符串解析为日期
	 * @param date 日期字符串
	 * @return 日期
	 * @author:Fisher
	 * @email:zhuangcaijin@126.com
	 */
    public static Date parseDate2(String date){
        if ((date == null) || (date.equals(""))) {
            return null;
        } 
        
        try {
        	SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
            return formatter.parse(date);
        } catch (ParseException e) {
            return null;
        }
        
    }
    
    /**
     * 给时间加上或减去指定毫秒，秒，分，时，天、月或年等，返回变动后的时间
     * @param date 要加减前的时间，如果不传，则为当前日期
     * @param field 时间域，有Calendar.MILLISECOND,Calendar.SECOND,Calendar.MINUTE,<br>
     *               Calendar.HOUR,Calendar.DATE, Calendar.MONTH,Calendar.YEAR
     * @param amount 按指定时间域加减的时间数量，正数为加，负数为减。
     * @return 变动后的时间
     * @author:Fisher
	 * @email:zhuangcaijin@126.com
     */
    public static Date add(Date date, int field, int amount) {
        if (date == null) {
            date = new Date();
        }

        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(field, amount);

        return cal.getTime();
    }
    
    /**
     * 给时间加上或减去指定毫秒，秒，分，时，天、月或年等，返回变动后的时间
     * @param date 要加减前的时间，如果不传，则为当前日期
     * @param amount 按指定时间域加减的时间数量，正数为加，负数为减。
     * @return 变动后的时间
     * @author:Fisher
	 * @email:zhuangcaijin@126.com
     */
    public static Date addDay(Date date, int amount) {
        return add(date, Calendar.DATE, amount);
    }
    
    /**
     * 获取参数时间所在那周周一的日期。
     * @param date 日期
     * @return 日期
     * @author:Fisher
	 * @email:zhuangcaijin@126.com
     */
    public static Date getFirstDayOfWeek(Date date){
    	if (date == null)date = getCurrentDate();
        Calendar c = new GregorianCalendar();
        c.setTime(date);//设置时间
        c.setFirstDayOfWeek(Calendar.MONDAY);//设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        int day = c.get(Calendar.DAY_OF_WEEK);//获得当前日期是一个星期的第几天
        if (day == 1) day = 8;
        c.add(Calendar.DATE, c.getFirstDayOfWeek()-day);//根据日历的规则，给当前日期减去星期几与一个星期第一天的差值 
    	return c.getTime();
    }
    
    /**
     * 比较两个时间的毫秒时间差
     * @param from 前一个时间
     * @param to 后一个时间
     * @return 返回to - from的毫秒差
     * @author:Fisher
	 * @email:zhuangcaijin@126.com
     */
    public static long compareTime(Date from, Date to){
    	if (from == null)from = getCurrentDate();
    	if (to == null)to = getCurrentDate();
    	
    	Calendar cFrom = Calendar.getInstance();
    	cFrom.setTime(from);
    	
    	Calendar cTo = Calendar.getInstance();
    	cTo.setTime(to);
    	
    	long millis  = cTo.getTimeInMillis() - cFrom.getTimeInMillis();
    	
    	return millis;
    	
    }
    
    /**
     * 得到某年某月最后一天日期
     * @param year 年
     * @param month 月
     * @return 日期
     * @author:Fisher
	 * @email:zhuangcaijin@126.com
     */
    public static Date getLastDayOfMonth(Integer year, Integer month){
    	if(null == year || null == month) {
    		return null;
    	}
    	Date date = UtilDatetime.parseDate("" +year + "-" + month + "-" + "1", "yyyy-MM-dd");
    	date = UtilDatetime.add(date, Calendar.MONTH, 1);
    	return UtilDatetime.add(date, Calendar.DATE, -1);
    }
}

